﻿using Nito.AsyncEx;
using System.Reflection;


namespace RuoYi.Framework.Core
{
    //
    // 摘要:
    //     Provides some helper methods to work with async methods.
    public static class AsyncHelper
    {
        //
        // 摘要:
        //     Checks if given method is an async method.
        //
        // 参数:
        //   method:
        //     A method to check
        public static bool IsAsync(this MethodInfo method)
        {
            Check.NotNull(method, "method");
            return method.ReturnType.IsTaskOrTaskOfT();
        }

        public static bool IsTaskOrTaskOfT(this Type type)
        {
            if (!(type == typeof(Task)))
            {
                if (type.GetTypeInfo().IsGenericType)
                {
                    return type.GetGenericTypeDefinition() == typeof(Task<>);
                }

                return false;
            }

            return true;
        }

        public static bool IsTaskOfT(this Type type)
        {
            if (type.GetTypeInfo().IsGenericType)
            {
                return type.GetGenericTypeDefinition() == typeof(Task<>);
            }

            return false;
        }

        //
        // 摘要:
        //     Returns void if given type is Task. Return T, if given type is Task{T}. Returns
        //     given type otherwise.
        public static Type UnwrapTask(Type type)
        {
            Check.NotNull(type, "type");
            if (type == typeof(Task))
            {
                return typeof(void);
            }

            if (type.IsTaskOfT())
            {
                return type.GenericTypeArguments[0];
            }

            return type;
        }

        //
        // 摘要:
        //     Runs a async method synchronously.
        //
        // 参数:
        //   func:
        //     A function that returns a result
        //
        // 类型参数:
        //   TResult:
        //     Result type
        //
        // 返回结果:
        //     Result of the async operation
        public static TResult RunSync<TResult>(Func<Task<TResult>> func)
        {
            return AsyncContext.Run(func);
        }

        //
        // 摘要:
        //     Runs a async method synchronously.
        //
        // 参数:
        //   action:
        //     An async action
        public static void RunSync(Func<Task> action)
        {
            AsyncContext.Run(action);
        }
    }
}
